home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / contrib / pdcurs22 / src / portable / window.c < prev   
Encoding:
C/C++ Source or Header  |  1995-01-26  |  15.8 KB  |  571 lines

  1. /*
  2. ***************************************************************************
  3. * This file comprises part of PDCurses. PDCurses is Public Domain software.
  4. * You may use this code for whatever purposes you desire. This software
  5. * is provided AS IS with NO WARRANTY whatsoever.
  6. * Should this software be used in another application, an acknowledgement
  7. * that PDCurses code is used would be appreciated, but is not mandatory.
  8. *
  9. * Any changes which you make to this software which may improve or enhance
  10. * it, should be forwarded to the current maintainer for the benefit of 
  11. * other users.
  12. *
  13. * The only restriction placed on this code is that no distribution of
  14. * modified PDCurses code be made under the PDCurses name, by anyone
  15. * other than the current maintainer.
  16. * See the file maintain.er for details of the current maintainer.
  17. ***************************************************************************
  18. */
  19. #define    CURSES_LIBRARY    1
  20. #include <curses.h>
  21.  
  22. /* undefine any macros for functions defined in this module */
  23. #undef    newwin
  24. #undef    delwin
  25. #undef    mvwin
  26. #undef    subwin
  27. #undef    derwin
  28. #undef    mvderwin
  29. #undef    dupwin
  30. #undef    wsyncup
  31. #undef    syncok
  32. #undef    wcursyncup
  33. #undef    wsyncdown
  34. #undef    resize_window
  35.  
  36. /* undefine any macros for functions called by this module if in debug mode */
  37. #ifdef PDCDEBUG
  38. #  undef    touchwin
  39. #  undef    wmove
  40. #  undef    overwrite
  41. #  undef    wmove
  42. #  undef    wclrtobot
  43. #endif
  44.  
  45. #ifdef PDCDEBUG
  46. char *rcsid_window  = "$Id$";
  47. #endif
  48.  
  49. /*man-start*********************************************************************
  50.  
  51.   Name:                                                        window
  52.  
  53.   Synopsis:
  54.       WINDOW *newwin(int nlines, int ncols, int begy, int begx);
  55.       int delwin(WINDOW *win);
  56.       int mvwin(WINDOW *win, int y, int x);
  57.       WINDOW *subwin(WINDOW* orig,int nlines,int ncols,
  58.               int begin_y,int begin_x);
  59.       WINDOW *derwin(WINDOW* orig,int nlines,int ncols,
  60.               int begin_y,int begin_x);
  61.       int mvderwin(WINDOW *win, int par_y, int par_x);
  62.       int dupwin(WINDOW *win);
  63.   ***    void wsyncup(WINDOW *win);
  64.   ***    int syncok(WINDOW *win, bool bf);
  65.   ***    void wcursyncup(WINDOW *win);
  66.   ***    void wsyncdown(WINDOW *win);
  67.  
  68.       WINDOW *resize_window(WINDOW *w, int lins, int cols);
  69.  
  70.   X/Open Description:
  71.      newwin() creates a new window with the given number of lines, 
  72.      nlines and columns, ncols. The upper left corner of the window is 
  73.      at line begy, column begx. If either nlines or ncols is zero,
  74.      they will be defaulted to LINES - begy and COLS - begx. A
  75.      new full-screen window is created by calling newwin(0, 0, 0, 0).
  76.  
  77.      delwin() deletes the named window, freeing all memory associated 
  78.      with it. In the case of overlapping windows, subwindows should be 
  79.      deleted before the main window.
  80.  
  81.      mvwin() moves the window so that the upper left-hand corner is at
  82.      position (y,x). If the move would cause the window to be off the
  83.      screen, it is an error and the window is not moved. Moving subwindows
  84.      is allowed, but should be avoided. (I don't know why ?).
  85.  
  86.      subwin() creates a new sub-window within a window.  The
  87.      dimensions of the sub-window are nlines lines and ncols
  88.      columns.  The sub-window is at position (begin_y, begin_x) on
  89.      the screen.  This position is relative to the screen, and not
  90.      to the window orig.
  91.      The sub-window is made in the middle of the window orig, so
  92.      that changes made to either window will affect both.  When
  93.      using this routine, it will often be necessary to call
  94.      touchwin() before calling wrefresh().
  95.  
  96.      derwin() is the same as subwin(), except that begin_y and
  97.      begin_x are relative to the origin of the window orig rather than
  98.      the screen.  There is no difference between subwindows and derived
  99.      windows.
  100.  
  101.      mvderwin() moves a derived window (or subwindow) inside its
  102.      parent window.  The screen-relative parameters of the window are not
  103.      changed.  This routine is used to dispay different parts of the parent
  104.      window at the same physical position on the screen.
  105.  
  106.      dupwin() creates an exact duplicate of the window win.
  107.  
  108.   PDCurses Description:
  109.      resize_window() does necessary initializations for the PDCurses 
  110.      package when doing screen size changes. The user is responsible for
  111.      deleting and/or resizing windows after this call is made.
  112.  
  113.      See the call PDC_resize_win().
  114.  
  115.      WARNING: This routine deallocated the existing stdscr, curscr
  116.      and modifies LINES, COLS and other internal PDCurses
  117.      variables.
  118.  
  119.   X/Open Return Value:
  120.      All functions return OK on success and ERR on error.
  121.  
  122.   X/Open Errors:
  123.      No errors are defined for this function.
  124.  
  125.   PDCurses Errors:
  126.      It is an error to call resize_window()function before calling initscr().
  127.      Also, an error will be generated if we fail to create a newly
  128.      sized replacement window for curscr, or stdscr.
  129.      This will typically happen when increasing the window size.
  130.  
  131.      NOTE:  If this happens, the previously successfully allocated
  132.      windows are left alone.  i.e. The resize is NOT cancelled for
  133.      those windows.
  134.  
  135.   Portability                             X/Open    BSD    SYS V
  136.                                           Dec '88
  137.       newwin                                Y        Y       Y
  138.       delwin                                Y        Y       Y
  139.       mvwin                                 Y        Y       Y
  140.       subwin                                Y        Y       Y
  141.       derwin                                Y        -       Y
  142.       mvderwin                              Y        -       Y
  143.       dupwin                                -        -      4.0
  144.       wsyncup                               -        -      4.0
  145.       syncok                                -        -      4.0
  146.       wcursyncup                            -        -      4.0
  147.       wsyncdown                             -        -      4.0
  148.       resize_window                         -        -       -
  149.  
  150. **man-end**********************************************************************/
  151.  
  152. /***********************************************************************/
  153. WINDOW*    newwin(int nlines, int ncols, int begy, int begx)
  154. /***********************************************************************/
  155. {
  156. extern    void*    (*mallc)( size_t );
  157. extern    void*    (*callc)( size_t, size_t );
  158. extern    void    (*fre)( void* );
  159.  
  160.     WINDOW*    win;
  161.     chtype*    ptr;
  162.     int    i;
  163.     int    j;
  164.  
  165. #ifdef PDCDEBUG
  166.     if (trace_on) PDC_debug("newwin() - called:lines=%d cols=%d begy=%d begx=%d\n",nlines,ncols,begy,begx);
  167. #endif
  168.  
  169.     if (nlines == 0)    nlines = LINES - begy;
  170.     if (ncols  == 0)    ncols  = COLS  - begx;
  171.  
  172.     if ((win = PDC_makenew(nlines, ncols, begy, begx)) == (WINDOW *) NULL)
  173.         return( (WINDOW *)NULL );
  174.  
  175.     for (i = 0; i < nlines; i++)
  176.     {
  177.         /*
  178.          * make and clear the lines
  179.          */
  180.         if ((win->_y[i] = (*callc)(ncols, sizeof(chtype))) == NULL)
  181.         {
  182.             for (j = 0; j < i; j++)
  183.             {
  184.                 /*
  185.                  * if error, free all the data
  186.                  */
  187.                 (*fre)(win->_y[j]);
  188.             }
  189.             (*fre)(win->_firstch);
  190.             (*fre)(win->_lastch);
  191.             (*fre)(win->_y);
  192.             (*fre)(win);
  193.             return( (WINDOW *)NULL );
  194.         }
  195.         else
  196.         {
  197.             for (ptr = win->_y[i];
  198.                  ptr < win->_y[i] + ncols;)
  199.             {
  200.                 /*
  201.                  * Retain the original screen attributes...
  202.                  */
  203.                 *ptr++ = _cursvar.blank;
  204.             }
  205.         }
  206.     }
  207. #ifdef UNIX
  208.     PDC_gotoxy(begy, begx);
  209. #endif
  210.     return( win );
  211. }
  212. /***********************************************************************/
  213. int    delwin(WINDOW *win)
  214. /***********************************************************************/
  215. {
  216. extern    void    (*fre)( void* );
  217.     int    i;
  218.  
  219. #ifdef PDCDEBUG
  220.     if (trace_on) PDC_debug("delwin() - called\n");
  221. #endif
  222.  
  223.  
  224.     if (win == (WINDOW *)NULL)
  225.         return( ERR );
  226.  
  227. #ifdef    REGISTERWINDOWS
  228.     _rmwin(win);        /* Remove from the visible windows list... */
  229. #endif
  230.  
  231.     /*
  232.      * FYI:  Subwindow's use 'parent's' lines
  233.      */
  234.     if (!(win->_flags & _SUBWIN)
  235.     &&  !(win->_flags & _SUBPAD))
  236.     {
  237.         for (i = 0; i < win->_pmaxy && win->_y[i]; i++)
  238.         {
  239.             if (win->_y[i] != NULL)
  240.                 (*fre)(win->_y[i]);
  241.         }
  242.     }
  243.     (*fre)(win->_firstch);
  244.     (*fre)(win->_lastch);
  245.     (*fre)(win->_y);
  246.     (*fre)(win);
  247.     return( OK );
  248. }
  249. /***********************************************************************/
  250. int    mvwin(WINDOW *win, int y, int x)
  251. /***********************************************************************/
  252. {
  253. #ifdef PDCDEBUG
  254.     if (trace_on) PDC_debug("mvwin() - called\n");
  255. #endif
  256.  
  257.     if (win == (WINDOW *)NULL)
  258.         return( ERR );
  259.  
  260.     if (y + win->_maxy > LINES || y < 0)
  261.         return( ERR );
  262.  
  263.     if (x + win->_maxx > COLS || x < 0)
  264.         return( ERR );
  265.  
  266.     win->_begy = y;
  267.     win->_begx = x;
  268.     touchwin(win);
  269.     return( OK );
  270. }
  271. /***********************************************************************/
  272. WINDOW*    subwin(WINDOW* orig,int nlines,int ncols,int begin_y,int begin_x)
  273. /***********************************************************************/
  274. {
  275. extern    void*    (*mallc)( size_t );
  276. extern    void*    (*callc)( size_t, size_t );
  277. extern    void    (*fre)( void* );
  278.  
  279.     WINDOW*    win;
  280.     int    i;
  281.     int    j = begin_y - orig->_begy;
  282.     int    k = begin_x - orig->_begx;
  283.  
  284. #ifdef PDCDEBUG
  285.     if (trace_on) PDC_debug("subwin() - called: lines %d cols %d begy %d begx %d\n",nlines,ncols,begin_y,begin_x);
  286. #endif
  287.  
  288.     if (!orig)
  289.         return( (WINDOW *)NULL );
  290.  
  291.     /*
  292.      * make sure window fits inside the original one
  293.      */
  294.     if ((begin_y < orig->_begy) ||
  295.         (begin_x < orig->_begx) ||
  296.         (begin_y + nlines) > (orig->_begy + orig->_maxy) ||
  297.         (begin_x + ncols)  > (orig->_begx + orig->_maxx))
  298.     {
  299.         return( (WINDOW *)NULL );
  300.     }
  301.     if (!nlines)    nlines = orig->_maxy - 1 - j;
  302.     if (!ncols)    ncols  = orig->_maxx - 1 - k;
  303.     if ((win = PDC_makenew(nlines, ncols, begin_y, begin_x)) == (WINDOW *) NULL)
  304.     {
  305.         return( (WINDOW *)NULL );
  306.     }
  307.  
  308.     /*
  309.      * initialize window variables
  310.      */
  311.     win->_attrs    = orig->_attrs;
  312. /* wrs (4/10/93) -- account for window background */
  313.     win->_bkgd    = orig->_bkgd;
  314.     win->_leave    = orig->_leave;
  315.     win->_scroll    = orig->_scroll;
  316.     win->_nodelay    = orig->_nodelay;
  317.     win->_use_keypad    = orig->_use_keypad;
  318.     win->_immed    = orig->_immed;
  319.     win->_pary    = j;
  320.     win->_parx    = k;
  321.     win->_parent    = orig;
  322.  
  323.     for (i = 0; i < nlines; i++)
  324.     {
  325.         win->_y[i] = (orig->_y[j++]) + k;
  326.     }
  327.  
  328.     win->_flags |= _SUBWIN;
  329.     return (win);
  330. }
  331. /***********************************************************************/
  332. WINDOW*    derwin(WINDOW* orig,int nlines,int ncols,int begin_y,int begin_x)
  333. /***********************************************************************/
  334. {
  335.     if (orig == (WINDOW *)NULL)
  336.         return( ERR );
  337.  
  338.     return subwin(orig, nlines, ncols, begin_y+orig->_begy, begin_x+orig->_begx);
  339. }
  340. /***********************************************************************/
  341. int    mvderwin( WINDOW* win, int par_y, int par_x )
  342. /***********************************************************************/
  343. {
  344.     int i, j;
  345.     WINDOW *mypar;
  346.  
  347.     if (win == (WINDOW *)NULL)
  348.         return( ERR );
  349.  
  350.     if( win->_parent == NULL )
  351.         return( ERR );
  352.  
  353.     mypar = win->_parent;
  354.  
  355.     if( par_y < 0 || par_x < 0 ||
  356.         (par_y + win->_maxy) > mypar->_maxy ||
  357.         (par_x + win->_maxx) > mypar->_maxx )
  358.     {
  359.         return( ERR );
  360.     }
  361.  
  362.     j = par_y;
  363.     for (i = 0; i < win->_maxy; i++)
  364.     {
  365.         win->_y[i] = (mypar->_y[j++]) + par_x;
  366.     }
  367.  
  368.     win->_pary    = par_y;
  369.     win->_parx    = par_x;
  370.  
  371.     return( OK );
  372. }
  373. /***********************************************************************/
  374. WINDOW*    dupwin( WINDOW* win )
  375. /***********************************************************************/
  376. {
  377. extern    void*    (*mallc)( size_t );
  378. extern    void*    (*callc)( size_t, size_t );
  379. extern    void    (*fre)( void* );
  380.  
  381.     WINDOW* new;
  382.     chtype* ptr;
  383.     chtype* ptr1;
  384.     int nlines, ncols, begy, begx;
  385.     int    i;
  386.     int    j;
  387.  
  388.     if (!win)
  389.         return( (WINDOW *)NULL );
  390.  
  391.     nlines    = win->_maxy;
  392.     ncols    = win->_maxx;
  393.     begy    = win->_begy;
  394.     begx    = win->_begx;
  395.  
  396.     if ((new = PDC_makenew(nlines, ncols, begy, begx)) == (WINDOW *) NULL)
  397.         return( (WINDOW *)NULL );
  398.  
  399. /* copy the contents of win into new */
  400.  
  401.     for (i = 0; i < nlines; i++)
  402.     {
  403.         if ((new->_y[i] = (*callc)(ncols, sizeof(chtype))) == NULL)
  404.         {
  405.             for (j = 0; j < i; j++)
  406.             {
  407.                 /*
  408.                  * if error, free all the data
  409.                  */
  410.                 (*fre)(new->_y[j]);
  411.             }
  412.             (*fre)(new->_firstch);
  413.             (*fre)(new->_lastch);
  414.             (*fre)(new->_y);
  415.             (*fre)(new);
  416.             return( (WINDOW *)NULL );
  417.         }
  418.         else
  419.         {
  420.             for (ptr = new->_y[i], ptr1 = win->_y[i];
  421.                  ptr < new->_y[i] + ncols;)
  422.             {
  423.                 *ptr++ = *ptr1++;
  424.             }
  425.         }
  426.     }
  427.  
  428.     new->_curx = win->_curx;
  429.     new->_cury = win->_cury;
  430.     new->_maxy = win->_maxy;
  431.     new->_maxx = win->_maxx;
  432.     new->_pmaxy = win->_pmaxy;
  433.     new->_pmaxx = win->_pmaxx;
  434.     new->_begy = win->_begy;
  435.     new->_begx = win->_begx;
  436.     new->_lastpy = win->_lastpy;
  437.     new->_lastpx = win->_lastpx;
  438.     new->_lastsy1 = win->_lastsy1;
  439.     new->_lastsx1 = win->_lastsx1;
  440.     new->_lastsy2 = win->_lastsy2;
  441.     new->_lastsx2 = win->_lastsx2;
  442.     new->_flags = win->_flags;
  443.     new->_attrs = win->_attrs;
  444.     new->_tabsize = win->_tabsize;
  445.     new->_clear = win->_clear;
  446.     new->_leave = win->_leave;
  447.     new->_scroll = win->_scroll;
  448.     new->_nodelay = win->_nodelay;
  449.     new->_use_keypad = win->_use_keypad;
  450.     new->_use_idl = win->_use_idl;
  451.     new->_use_idc = win->_use_idc;
  452.     new->_tmarg = win->_tmarg;
  453.     new->_bmarg = win->_bmarg;
  454.     new->_title = win->_title;
  455.     new->_title_ofs = win->_title_ofs;
  456.     new->_title_attr = win->_title_attr;
  457.     new->_blank = win->_blank;
  458.     new->_parx = win->_parx;
  459.     new->_pary = win->_pary;
  460.     new->_parent = win->_parent;
  461.     new->_bkgd = win->_bkgd;
  462.  
  463.     for (i = 0; i < nlines; i++)
  464.     {
  465.         new->_firstch[i] = 0;
  466.         new->_lastch[i] = ncols - 1;
  467.     }
  468.  
  469.     new->_flags = win->_flags;
  470.  
  471.     return( new );
  472.  
  473. }
  474. /***********************************************************************/
  475. WINDOW*    resize_window(WINDOW *w, int lins, int cols)
  476. /***********************************************************************/
  477. {
  478. extern    void*    (*mallc)();    /* ptr to some malloc(size)    */
  479. extern    void*    (*callc)();    /* ptr to some ecalloc(num,size)*/
  480. extern    void    (*fre)();    /* ptr to some free(ptr)    */
  481.  
  482.     WINDOW*    new;
  483.     int    ncols  = max(cols, w->_pmaxx);
  484.     int    nlines = max(lins, w->_pmaxy);
  485.     int    i;
  486.     int    j;
  487.  
  488. #ifdef PDCDEBUG
  489.     if (trace_on) PDC_debug("resize_window() - called: lins %d cols %d\n",lins,cols);
  490. #endif
  491.  
  492.     if (w == (WINDOW *)NULL)
  493.         return( (WINDOW *)NULL );
  494.  
  495.     if ((lins > w->_pmaxy) || (cols > w->_pmaxx))
  496.     {
  497.         if ((new = PDC_makenew(nlines, ncols, w->_begy, w->_begx)) == (WINDOW *)NULL)
  498.             return( (WINDOW *)NULL );
  499.  
  500.         new->_curx = w->_curx;
  501.         new->_cury = w->_cury;
  502.         new->_flags = w->_flags;
  503.         new->_attrs = w->_attrs;
  504.         new->_tabsize = w->_tabsize;
  505.         new->_clear = w->_clear;
  506.         new->_leave = w->_leave;
  507.         new->_scroll = w->_scroll;
  508.         new->_nodelay = w->_nodelay;
  509.         new->_use_keypad = w->_use_keypad;
  510.         new->_tmarg = w->_tmarg;
  511.         new->_bmarg = w->_bmarg;
  512.         new->_title = w->_title;
  513.         new->_title_ofs = w->_title_ofs;
  514.         new->_title_attr = w->_title_attr;
  515.         new->_parent = w->_parent;
  516. #if 0
  517.         memcpy(new->_borderchars, w->_borderchars, 8*sizeof(chtype));
  518. #endif
  519.  
  520.         for (i = 0; i < nlines; i++)
  521.         {
  522.             /*
  523.              * make and clear the lines
  524.              */
  525.             if ((new->_y[i] = (chtype*)(*callc)(ncols, sizeof(chtype))) == NULL)
  526.             {
  527.                 for (j = 0; j < i; j++)
  528.                 {
  529.                     /*
  530.                      * if error, free all the data
  531.                      */
  532.                     (*fre)(new->_y[j]);
  533.                 }
  534.                 (*fre)(new->_firstch);
  535.                 (*fre)(new->_lastch);
  536.                 (*fre)(new->_y);
  537.                 (*fre)(new);
  538.                 return( (WINDOW *)NULL );
  539.             }
  540.         }
  541.         if ((w != curscr))
  542.         {
  543.             overwrite(w, new);
  544.             wmove(new, w->_maxy - 1, 0);
  545.             wclrtobot(new);
  546. #if 0
  547. /* JGB box uses defaults if arguments are zero, but we don't want to do
  548.    this if the window currently has no box */
  549.             if (w->_borderchars[0] || w->_borderchars[2])
  550.                 box(new, w->_borderchars[0], w->_borderchars[2]);
  551. #endif
  552.         }
  553.         delwin(w);
  554.         return( new );
  555.     }
  556.     else
  557.     {
  558.         w->_bmarg = lins - 1;
  559.         w->_maxy = lins;
  560.         w->_maxx = cols;
  561. #if 0
  562. /* JGB box uses defaults if arguments are zero, but we don't want to do
  563.    this if the window currently has no box */
  564.         if (w->_borderchars[0] || w->_borderchars[2])
  565.             box(w, w->_borderchars[0], w->_borderchars[2]);
  566. #endif
  567.         return( w );
  568.     }
  569. }
  570.